/* Papastefanos Serafeim */
/* Sunarthseis gia parsing mhnumatwn soap */

#include <stdio.h>
#include <stdlib.h>
#include "ixml.h"
#include "client.h"
#include "soaparse.h"
#include "custom.h"
#include "helpers.h"

/************************************/
/********** PARSE STARTING **********/
/************************************/
SoapMessage *parseStart(char *buf) {
	IXML_Document* doc;

	SoapMessage *tmp = (SoapMessage *)malloc(sizeof(SoapMessage) );
	tmp->header=NULL;

	if( ixmlParseBufferEx(buf, &doc)!=IXML_SUCCESS) {
		PRINTD("Error while parsing the XML buffer, not an xml message.\n");
		return NULL;
	}

	IXML_Node* envelope=ixmlNode_getFirstChild( (IXML_Node*) doc);
	IXML_Node* el=ixmlNode_getFirstChild( (IXML_Node*)envelope);
	if( strcmp( (char *)ixmlNode_getNodeName(el), "soap:Header")==0) {
		tmp->header = parseHeader(el);
		/* go to body */
		el=ixmlNode_getNextSibling( (IXML_Node*)el);
	}

	if( strcmp( (char *)ixmlNode_getNodeName(el), "soap:Body")!=0) {
		PRINTD("Error while parsing the XML Buffer, no soap:Body found.\n");
		if(tmp->header!=NULL) free(tmp->header);
		return NULL;
	}

	el=ixmlNode_getFirstChild( (IXML_Node*)el);

	tmp->message = ixmlNode_cloneNode(el, TRUE);

	if( strcmp( (char *)ixmlNode_getNodeName(el), "cwmp:Inform")==0) {
		PRINTD("\nInform\n");
		tmp->type=INFORM;
		ixmlNode_free((IXML_Node *)doc);
		return tmp;
	} else if( strcmp( (char *)ixmlNode_getNodeName(el), "cwmp:InformResponse")==0) {
		PRINTD("\nInformResponse\n");
		tmp->type=INFORMRESPONSE;
		ixmlNode_free((IXML_Node *)doc);
		return tmp;
	} else if( strcmp( (char *)ixmlNode_getNodeName(el), "cwmp:SetParameterValues")==0) {
		PRINTD("\nSetParameterValues\n");
		tmp->type=SETPARAMETERVALUES;
		ixmlNode_free((IXML_Node *)doc);
		return tmp;
	} else if( strcmp( (char *)ixmlNode_getNodeName(el), "cwmp:SetParameterValuesResponse")==0) {
		PRINTD("\nSetParameterValuesResponse\n");
		tmp->type=SETPARAMETERVALUESRESPONSE;
		ixmlNode_free((IXML_Node *)doc);
		return tmp;
	} else if( strcmp( (char *)ixmlNode_getNodeName(el), "cwmp:GetParameterValues")==0) {
		PRINTD("\nGetParameterValues\n");
		tmp->type=GETPARAMETERVALUES;
		ixmlNode_free((IXML_Node *)doc);
		return tmp;
	} else if( strcmp( (char *)ixmlNode_getNodeName(el), "cwmp:GetParameterValuesResponse")==0) {
		PRINTD("\nGetParameterValuesResponse\n");
		tmp->type=GETPARAMETERVALUESRESPONSE;
		ixmlNode_free((IXML_Node *)doc);
		return tmp;
	} else if( strcmp( (char *)ixmlNode_getNodeName(el), "cwmp:GetParameterNames")==0) {
		PRINTD("\nGetParameterNames\n");
		tmp->type=GETPARAMETERNAMES;
		ixmlNode_free((IXML_Node *)doc);
		return tmp;
	} else if( strcmp( (char *)ixmlNode_getNodeName(el), "cwmp:GetParameterNamesResponse")==0) {
		PRINTD("\nGetParameterNamesResponse\n");
		tmp->type=GETPARAMETERNAMESRESPONSE;
		ixmlNode_free((IXML_Node *)doc);
		return tmp;
	} else if( strcmp( (char *)ixmlNode_getNodeName(el), "cwmp:GetRPCMethods")==0) {
		PRINTD("\nGetRPCMethods\n");
		tmp->type=GETRPCMETHODS;
		ixmlNode_free((IXML_Node *)doc);
		return tmp;
	} else if( strcmp( (char *)ixmlNode_getNodeName(el), "cwmp:Reboot")==0) {
		PRINTD("\nReboot\n");
		tmp->type=REBOOT;
		ixmlNode_free((IXML_Node *)doc);
		return tmp;
	} else if( strcmp( (char *)ixmlNode_getNodeName(el), "cwmp:Download")==0) {
		PRINTD("\nDownload\n");
		tmp->type=DOWNLOAD;
		ixmlNode_free((IXML_Node *)doc);
		return tmp;
	} else if( strcmp( (char *)ixmlNode_getNodeName(el), "cwmp:Upload")==0) {
		PRINTD("\nUpload\n");
		tmp->type=UPLOAD;
		ixmlNode_free((IXML_Node *)doc);
		return tmp;
	} else {
		PRINTD("Not implemented RPC method");
		tmp->type=NOTIMPLEMENTEDMESSAGE;
		ixmlNode_free((IXML_Node *)doc);
		return tmp;
	}
}

/************************************/
/********** INFORM PARSING **********/
/************************************/

int parseInform(IXML_Node *node, DeviceIdStruct *deviceId, EventList *eventList, unsigned int *maxEnvelopes, DateTime *currentTime, unsigned int *retryCount, ParameterValueList *parameterList) {

	IXML_Node* devid=ixmlNode_getFirstChild(node);
	if( strcmp( (char *)ixmlNode_getNodeName(devid), "DeviceId")!=0) {
		PRINTD("Error while parsing the Inform message (DeviceId).");
		return -INVALID_ARGUMENTS ; // ERRORRR
	}

	IXML_Node* evt=ixmlNode_getNextSibling(devid);
	if( strcmp( (char *)ixmlNode_getNodeName(evt), "Event")!=0) {
		PRINTD("Error while parsing the Inform message (Event).");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}

	IXML_Node* maxenvs=ixmlNode_getNextSibling(evt);
	if( strcmp( (char *)ixmlNode_getNodeName(maxenvs), "MaxEnvelopes")!=0) {
		PRINTD("Error while parsing the Inform message (MaxEnvelopes).");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}

	IXML_Node* ct=ixmlNode_getNextSibling(maxenvs);
	if( strcmp( (char *)ixmlNode_getNodeName(ct), "CurrentTime")!=0) {
		PRINTD("Error while parsing the Inform message (CurrentTime).");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}


	IXML_Node* retryc=ixmlNode_getNextSibling(ct);
	if( strcmp( (char *)ixmlNode_getNodeName(retryc), "RetryCount")!=0) {
		PRINTD("Error while parsing the Inform message (RetryCount).");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}

	IXML_Node* paramlist=ixmlNode_getNextSibling(retryc);
	if( strcmp( (char *)ixmlNode_getNodeName(paramlist), "ParameterList")!=0) {
		PRINTD("Error while parsing the Inform message (ParameterList).");
		return -INVALID_ARGUMENTS ; // ERRORRR
	}

	/************** Parsing the DeviceId *****************/
	IXML_Node* manuf=ixmlNode_getFirstChild(devid);
	if( strcmp( (char *)ixmlNode_getNodeName(manuf), "Manufacturer")!=0) {
		PRINTD("Error while parsing the Inform message (DeviceId, Manufacturer)");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}
	IXML_Node* manuf_text=ixmlNode_getFirstChild(manuf);
	deviceId->manufactorer=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(manuf_text));

	IXML_Node* oui=ixmlNode_getNextSibling(manuf);
	if( strcmp( (char *)ixmlNode_getNodeName(oui), "OUI")!=0) {
		PRINTD("Error while parsing the Inform message (DeviceId, OUI)");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}
	IXML_Node* oui_text=ixmlNode_getFirstChild(oui);
	deviceId->OUI=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(oui_text));

	IXML_Node* pclass=ixmlNode_getNextSibling(oui);
		if( strcmp( (char *)ixmlNode_getNodeName(pclass), "ProductClass")!=0) {
		PRINTD("Error while parsing the Inform message (DeviceId, ProductClass)");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}
	IXML_Node* pclass_text=ixmlNode_getFirstChild(pclass);
	deviceId->productClass=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(pclass_text));

	IXML_Node* snum=ixmlNode_getNextSibling(pclass);
		if( strcmp( (char *)ixmlNode_getNodeName(snum), "SerialNumber")!=0) {
		PRINTD("Error while parsing the Inform message (DeviceId, SerialNumber)");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}
	IXML_Node* snum_text=ixmlNode_getFirstChild(snum);
	deviceId->serialNumber=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(snum_text));

	/************** Parsing the events *****************/
	IXML_NodeList* event_list=ixmlNode_getChildNodes(evt);
	eventList->size = ixmlNodeList_length(event_list);
//	PRINTD("Found %d events.\n", *numOfEvents);
	unsigned long int i;
	eventList->events = (EventStruct *)malloc(eventList->size*sizeof(EventStruct) );
	for(i=0;i<eventList->size;i++) {
		IXML_Node *evnt = ixmlNodeList_item(event_list, i);
		if( strcmp( (char *)ixmlNode_getNodeName(evnt), "EventCode")!=0) {
			PRINTD("Error while parsing the Inform message (Event, EventCode)");
			return -INVALID_ARGUMENTS  ; // ERRORRR
		}
		IXML_Node *evtcode = ixmlNode_getFirstChild(evnt);
		eventList->events[i].eventCode=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(evtcode));
		
	}
	ixmlNodeList_free(event_list);

	/************** Parsing max envelops *****************/
	IXML_Node* maxenvs_txt=ixmlNode_getFirstChild(maxenvs);	
	char *buf = (char *)ixmlNode_getNodeValue(maxenvs_txt);
	*maxEnvelopes=atoi(buf);

	/************** Parsing current time*****************/
	IXML_Node* ct_txt=ixmlNode_getFirstChild(ct);
	buf = (char *)ixmlNode_getNodeValue(ct_txt);	
	*currentTime = *ascitodate(buf);

	/************** Parsing retry count*****************/
	IXML_Node* retryc_txt=ixmlNode_getFirstChild(retryc);
	buf = (char *)ixmlNode_getNodeValue(retryc_txt);
	*retryCount = atoi(buf);
		
	/************** Parsing parameter list*****************/
	IXML_NodeList* parval_list=ixmlNode_getChildNodes(paramlist);
	parameterList->size = ixmlNodeList_length(parval_list);
//	PRINTD("Found %d params.\n", *numOfParams);
	parameterList->parameters = (ParameterValueStruct *)malloc(parameterList->size*sizeof(ParameterValueStruct) );
	for(i=0;i<parameterList->size;i++) {
		IXML_Node *parval = ixmlNodeList_item(parval_list, i);

		IXML_Node *name = ixmlNode_getFirstChild(parval);
		if( strcmp( (char *)ixmlNode_getNodeName(name), "Name")!=0) {
			PRINTD("Error while parsing the Inform message (ParameterValues, Name)");
			return -INVALID_ARGUMENTS  ; // ERRORRR
		}
		IXML_Node *name_text = ixmlNode_getFirstChild(name);
		parameterList->parameters[i].name=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(name_text));
		IXML_Node *value = ixmlNode_getNextSibling(name);
		if( strcmp( (char *)ixmlNode_getNodeName(value), "Value")!=0) {
			PRINTD("Error while parsing the Inform message (ParameterValues, Value)");
			return -INVALID_ARGUMENTS  ; // ERRORRR
		}
		IXML_Node *value_text = ixmlNode_getFirstChild(value);
		parameterList->parameters[i].value=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(value_text));
	}
	ixmlNodeList_free(parval_list);

	ixmlNode_free(node);
	return 0;
}

int parseInformResponse(IXML_Node *node, unsigned int *maxEnvelopes) {
	/* Going to <MaxEnvelopes> element */
	IXML_Node* maxenvs=ixmlNode_getFirstChild(node); 
	if( strcmp( (char *)ixmlNode_getNodeName(maxenvs), "MaxEnvelopes")!=0) {
			PRINTD("Error while parsing the InformResponse message.");
			return -INVALID_ARGUMENTS ; // Error, invalid arguments 
	}
	/* Going to the text child */
	IXML_Node* maxenvs_txt=ixmlNode_getFirstChild(maxenvs);
	char *buf = (char *)ixmlNode_getNodeValue(maxenvs_txt);
	*maxEnvelopes=atoi(buf);
	if(*maxEnvelopes < 1) {
		PRINTD("Error while parsing the InformResponse message.");
		// Error, maxEnvelopes must be > 0
		return -INVALID_ARGUMENTS;
	}
	ixmlNode_free(node);
	return 0;
}

/************************************************/
/********** SETPARAMETERVALUES PARSING **********/
/************************************************/

int parseSetParameterValues(IXML_Node *node, ParameterValueList *parameterList, char **parameterKey) {
	/* Going to <ParameterList> element */
	IXML_Node* paramlist=ixmlNode_getFirstChild(node);
	if( strcmp( (char *)ixmlNode_getNodeName(paramlist), "ParameterList")!=0) {
			PRINTD("Error while parsing the SetParameterValues message (ParameterList)");
			return -INVALID_ARGUMENTS ;
	}

	/* Getting the <ParameterValueStruct> elements */
	IXML_NodeList* parval_list=ixmlNode_getChildNodes(paramlist);

	parameterList->size = ixmlNodeList_length(parval_list);
//	PRINTD("Found %d params.\n", *numOfParams);

	unsigned long int i;

	parameterList->parameters = (ParameterValueStruct *)malloc(parameterList->size*sizeof(ParameterValueStruct) );
	for(i=0;i<parameterList->size;i++) {
		IXML_Node *parval = ixmlNodeList_item(parval_list, i);

		IXML_Node *name = ixmlNode_getFirstChild(parval);
		if( name == NULL || strcmp( (char *)ixmlNode_getNodeName(name), "Name")!=0) {
			PRINTD("Error while parsing the SetParameterValues message (ParameterValueStruct, Name)");
			return -INVALID_ARGUMENTS ; 
		}
		IXML_Node *name_text = ixmlNode_getFirstChild(name);
		parameterList->parameters[i].name=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(name_text));
		IXML_Node *value = ixmlNode_getNextSibling(name);
		if( strcmp( (char *)ixmlNode_getNodeName(value), "Value")!=0) {
			PRINTD("Error while parsing the SetParameterValues message (ParameterValueStruct, Value)");
			return -INVALID_ARGUMENTS ; 
		}
		IXML_Node *value_text = ixmlNode_getFirstChild(value);
		parameterList->parameters[i].value=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(value_text));
	}
	ixmlNodeList_free(parval_list);

	IXML_Node* pkey=ixmlNode_getNextSibling(paramlist);
	IXML_Node *pkey_text = ixmlNode_getFirstChild(pkey);
	*parameterKey=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(pkey_text));
	if(*parameterKey == NULL) *parameterKey = "";

	ixmlNode_free(node);
	return 0;
}

int parseSetParameterValuesResponse(IXML_Node *node, unsigned int *status) {
	/* Going to <Status> element */
	IXML_Node* stat=ixmlNode_getFirstChild(node);
	if( strcmp( (char *)ixmlNode_getNodeName(stat), "Status")!=0) {
		PRINTD("Error while parsing the SetParameterValuesResponse message (Status)");
		return -INVALID_ARGUMENTS ; // ERRORRR
	}
	/* Going to the text child */
	IXML_Node* stat_txt=ixmlNode_getFirstChild(stat);
	char *buf = (char *)ixmlNode_getNodeValue(stat_txt);
	*status=atoi(buf);
	ixmlNode_free(node);
	return 0;
}

/************************************************/
/********** GETPARAMETERVALUES PARSING **********/
/************************************************/

int parseGetParameterValues(IXML_Node *node, StringList *parameterNames) {
	IXML_Node* names=ixmlNode_getFirstChild(node);
	if( strcmp( (char *)ixmlNode_getNodeName(names), "ParameterNames")!=0) {
		PRINTD("Error while parsing the GetParameterValues message (ParameterNames)");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}

	IXML_NodeList* name_list=ixmlNode_getChildNodes(names);
	//puts( (char *)ixmlNode_getNodeName(names) );
	parameterNames->size = ixmlNodeList_length(name_list);
	parameterNames->strings = (char **)malloc(parameterNames->size*sizeof(char *) );
	unsigned int i;
	for(i=0;i<parameterNames->size;i++) {
		IXML_Node *name = ixmlNodeList_item(name_list, i);

		IXML_Node *name_text = ixmlNode_getFirstChild(name);
	//	puts( (char *)ixmlNode_getNodeName(name) );
		parameterNames->strings[i] =(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(name_text));
	
	}
	ixmlNodeList_free(name_list);
	ixmlNode_free(node);
	return 0;
} 

int parseGetParameterValuesResponse(IXML_Node *node, ParameterValueList *parameterList) {
	/* Going to <ParameterList> element */
	IXML_Node* paramlist=ixmlNode_getFirstChild(node); 
	if( strcmp( (char *)ixmlNode_getNodeName(paramlist), "ParameterList")!=0) {
		PRINTD("Error while parsing the GetParameterValuesResponse message (ParameterList)");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}

	/* Getting the <ParameterValueStruct> elements */
	IXML_NodeList* parval_list=ixmlNode_getChildNodes(paramlist);

	parameterList->size = ixmlNodeList_length(parval_list);
//	PRINTD("Found %d params.\n", *numOfParams);

	unsigned long int i;

	parameterList->parameters = (ParameterValueStruct *)malloc(parameterList->size*sizeof(ParameterValueStruct) );
	for(i=0;i<parameterList->size;i++) {
		IXML_Node *parval = ixmlNodeList_item(parval_list, i);
		
		IXML_Node *name = ixmlNode_getFirstChild(parval);
		if( strcmp( (char *)ixmlNode_getNodeName(name), "Name")!=0) {
			PRINTD("Error while parsing the GetParameterValuesResponse message (ParameterList, ParameterValueStruct, Name)");
			return -INVALID_ARGUMENTS  ; // ERRORRR
		}
		IXML_Node *name_text = ixmlNode_getFirstChild(name);
		parameterList->parameters[i].name=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(name_text));
		IXML_Node *value = ixmlNode_getNextSibling(name);
		if( strcmp( (char *)ixmlNode_getNodeName(parval), "Value")!=0) {
			PRINTD("Error while parsing the GetParameterValuesResponse message (ParameterList, ParameterValueStruct, Vali=ue)");
			return -INVALID_ARGUMENTS  ; // ERRORRR
		}
		IXML_Node *value_text = ixmlNode_getFirstChild(value);
		parameterList->parameters[i].value=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(value_text));
	}
	ixmlNodeList_free(parval_list);
	ixmlNode_free(node);
	return 0;

}


/************************************************/
/*********** GETPARAMETERNAMES PARSING **********/
/************************************************/

int parseGetParameterNames(IXML_Node *node, char **pathName, unsigned short *nextLevel) {
	IXML_Node* path=ixmlNode_getFirstChild(node);
	if( strcmp( (char *)ixmlNode_getNodeName(path), "ParameterPath")!=0) {
		PRINTD("Error while parsing the GetParameterNames message (ParameterPath)");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}
	
	IXML_Node *path_text = ixmlNode_getFirstChild(path);
	*pathName=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(path_text));
	if(*pathName == NULL) *pathName = strdup("");

	IXML_Node* nlevel=ixmlNode_getNextSibling(path);
	if( strcmp( (char *)ixmlNode_getNodeName(nlevel), "NextLevel")!=0) {
		PRINTD("Error while parsing the GetParameterNames message (NextLevel)");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}

	IXML_Node *nlevel_text = ixmlNode_getFirstChild(nlevel);
	*nextLevel=(strcmp(ixmlNode_getNodeValue(nlevel_text),"false")==0)?0:1;


	ixmlNode_free(node);
	return 0;
} 

int parseGetParameterNamesResponse(IXML_Node *node, StringList *parameterNames) {
// DE XREIAZETAI STON CLIENT
	return 0;

}

/************************************************/
/************* GETRPCMETHODS PARSING ************/
/************************************************/

int parseGetRPCMethods(IXML_Node *node) {
// Ousiastika de ginetai kapoio parsing afou h me9odos auth den exei arguments
// ara epistrefetai kateu9eian to 0
	return 0;
}

int parseGetRPCMethodsResponse(IXML_Node *node, StringList *resp) {
// DE XREIAZETAI STON CLIENT
	return 0;
}


/************************************************/
/**************** REBOOT PARSING ****************/
/************************************************/
int parseReboot(IXML_Node *node, char **cmdKey) {
	IXML_Node* cmd=ixmlNode_getFirstChild(node);
	if( strcmp( (char *)ixmlNode_getNodeName(cmd), "CommandKey")!=0) {
		PRINTD("Error while parsing the Reboot message (CommandKey)");
		return -INVALID_ARGUMENTS ; // ERRORRR
	}
	
	IXML_Node *cmd_text = ixmlNode_getFirstChild(cmd);
	*cmdKey=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(cmd_text));
	if(*cmdKey == NULL) *cmdKey = "";
	return 0;
}


int parseRebootRespones(IXML_Node *node) {
// DE XREIAZETAI STON CLIENT
	return 0;	
}

/************************************************/
/***************** UPLOAD PARSING ***************/
/************************************************/
int parseUpload(IXML_Node *node, char **cmdKey, char **fileType, char **URL, char **userName, char **passWord, unsigned int *delaySeconds) {
	IXML_Node* cmd_el=ixmlNode_getFirstChild(node);
	if( strcmp( (char *)ixmlNode_getNodeName(cmd_el), "CommandKey")!=0) {
		PRINTD("Error while parsing the Upload message (CommandKey)");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}
	
	IXML_Node *cmd_text = ixmlNode_getFirstChild(cmd_el);
	*cmdKey=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(cmd_text));
	if(*cmdKey == NULL) *cmdKey = strdup("");

	IXML_Node* ftype_el=ixmlNode_getNextSibling(cmd_el);
	if( strcmp( (char *)ixmlNode_getNodeName(ftype_el), "FileType")!=0) {
		PRINTD("Error while parsing the Upload message (FileType)");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}

	IXML_Node *ftype_text = ixmlNode_getFirstChild(ftype_el);
	*fileType=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(ftype_text));
	if(*fileType == NULL) return -INVALID_ARGUMENTS ; // ERROR

	IXML_Node* URL_el=ixmlNode_getNextSibling(ftype_el);
	if( strcmp( (char *)ixmlNode_getNodeName(URL_el), "URL")!=0) {
		PRINTD("Error while parsing the Upload message (URL)");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}

	IXML_Node *URL_text = ixmlNode_getFirstChild(URL_el);
	*URL=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(URL_text));
	if(*URL == NULL) return -INVALID_ARGUMENTS ; // ERROR

	IXML_Node* uname_el=ixmlNode_getNextSibling(URL_el);
	if( strcmp( (char *)ixmlNode_getNodeName(uname_el), "Username")!=0) {
		PRINTD("Error while parsing the Upload message (UserName)");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}

	IXML_Node *uname_text = ixmlNode_getFirstChild(uname_el);
	*userName=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(uname_text));
	if(*userName == NULL) *userName = strdup("");

	IXML_Node* pwd_el=ixmlNode_getNextSibling(uname_el);
	if( strcmp( (char *)ixmlNode_getNodeName(pwd_el), "Password")!=0) {
		PRINTD("Error while parsing the Upload message (PassWord)");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}

	IXML_Node *pwd_text = ixmlNode_getFirstChild(pwd_el);
	*passWord=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(pwd_text));
	if(*passWord == NULL) *passWord = strdup("");

	IXML_Node* dsecs_el=ixmlNode_getNextSibling(pwd_el);
	if( strcmp( (char *)ixmlNode_getNodeName(dsecs_el), "DelaySeconds")!=0) {
		PRINTD("Error while parsing the Upload message (DelaySeconds)");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}

	IXML_Node *dsecs_text = ixmlNode_getFirstChild(dsecs_el);
	
	char *buf = (char *)ixmlNode_getNodeValue(dsecs_text);
	*delaySeconds=atoi(buf);


	ixmlNode_free(node);
	return 0;
}


int parseUploadRespones(IXML_Node *node, short int *status, DateTime *startTime, DateTime *completeTime) {
// DE XREIAZETAI STON CLIENT
	return 0;	
}


/************************************************/
/*************** DOWNLOAD PARSING ***************/
/************************************************/
int parseDownload(IXML_Node *node, char **cmdKey, char **fileType, char **URL, char **userName, char **passWord, unsigned int *fileSize, char **targetFileName, unsigned int *delaySeconds, char **successURL, char **failureURL) {
	IXML_Node* cmd_el=ixmlNode_getFirstChild(node);
	*cmdKey = getNodeText(cmd_el, "CommandKey");
	if(*cmdKey == NULL) {
		PRINTD("Error while parsing the download message (filetype)");
		return -INVALID_ARGUMENTS  ; // ERRORRR
	}


	IXML_Node* ftype_el=ixmlNode_getNextSibling(cmd_el);
	*fileType = getNodeText(ftype_el, "FileType");

	if(*fileType == NULL||strcmp(*fileType,"")==0) {
		PRINTD("Error while parsing the download message (filetype)");
		return -INVALID_ARGUMENTS ;
	}

	IXML_Node* URL_el=ixmlNode_getNextSibling(ftype_el);
	*URL = getNodeText(URL_el, "URL");
	if(*URL==NULL || strcmp(*URL,"")==0) {
		PRINTD("Error while parsing the download message (URL)");
		return -INVALID_ARGUMENTS ;
	}

	IXML_Node* userName_el=ixmlNode_getNextSibling(URL_el);
	*userName = getNodeText(userName_el, "Username");
	if(*userName == NULL) {
		PRINTD("Error while parsing the download message (username)");
		return -INVALID_ARGUMENTS ;
	}

	IXML_Node* passWord_el=ixmlNode_getNextSibling(userName_el);
	*passWord = getNodeText(passWord_el, "Password");
	if(passWord == NULL) {
		PRINTD("Error while parsing the download message (password)");
		return -INVALID_ARGUMENTS ;
	}



	IXML_Node* fsize_el=ixmlNode_getNextSibling(passWord_el);
	char *buf = getNodeText(fsize_el, "FileSize");
	if(buf == NULL) {
		PRINTD("Error while parsing the download message (filesize)");
		return -INVALID_ARGUMENTS ;
	}

	*fileSize = atoi(buf);
	free(buf);


	
	IXML_Node* tget_el=ixmlNode_getNextSibling(fsize_el);
	*targetFileName = getNodeText(tget_el, "TargetFileName");
	if(targetFileName == NULL || strcmp(*targetFileName,"")==0) {
		PRINTD("Error while parsing the download message (target fname)");
		return -INVALID_ARGUMENTS ;
	}



	IXML_Node* dsecs_el=ixmlNode_getNextSibling(tget_el);
	buf = getNodeText(dsecs_el, "DelaySeconds");
	if(buf == NULL ) {
		PRINTD("Error while parsing the download message (delay seconds)");
		return -INVALID_ARGUMENTS ;
	}
	*delaySeconds = atoi(buf);
	free(buf);




	IXML_Node* surl_el=ixmlNode_getNextSibling(dsecs_el);
	*successURL = getNodeText(surl_el, "SuccessURL");
	if(successURL == NULL ) {
		PRINTD("Error while parsing the download message (success url)");
		return -INVALID_ARGUMENTS ;
	}


	IXML_Node* furl_el=ixmlNode_getNextSibling(surl_el);
	*failureURL = getNodeText(furl_el, "FailureURL");	
	if(failureURL == NULL ) {
		PRINTD("Error while parsing the download message (fail url)");
		return -INVALID_ARGUMENTS ;
	}


	ixmlNode_free(node);
	
	return 0;	
}

int parseDownloadRespones(IXML_Node *node, short int *status, DateTime *stime, DateTime *ctime) {
// DE XREIAZETAI STON CLIENT
	return 0;	
}


/************************************************/
/**************** HEADER PARSING ****************/
/************************************************/

SoapHeader *parseHeader(IXML_Node *node) {
	SoapHeader *tmp = (SoapHeader *)malloc(sizeof(SoapHeader) );
	tmp->id = NULL;
	tmp->holdRequests=0;
	tmp->noMoreRequests=0;
	unsigned int i;
	IXML_NodeList* head_list=ixmlNode_getChildNodes(node);

	unsigned int len = ixmlNodeList_length(head_list);

	for(i=0;i<len;i++) {
		IXML_Node *el = ixmlNodeList_item(head_list, i);
		char *name = (char *)ixmlNode_getNodeName(el);
		IXML_Node *el_text = ixmlNode_getFirstChild(el);
		if(strcmp(name,"cwmp:ID")==0) tmp->id = (char *)ixmlCloneDOMString(ixmlNode_getNodeValue(el_text));
		if(strcmp(name,"cwmp:HoldRequests")==0) tmp->holdRequests = atoi( (char *)ixmlNode_getNodeValue(el_text) );
		if(strcmp(name,"cwmp:NoMoreRequests")==0) tmp->noMoreRequests = atoi( (char *)ixmlNode_getNodeValue(el_text) );
	}
	ixmlNodeList_free(head_list);
	return tmp;
}

char *getNodeText(IXML_Node *node, char *nameOfNode) {
	char *tmp;
	if( strcmp( (char *)ixmlNode_getNodeName(node), nameOfNode)!=0) {
		PRINTD("Error while parsing a node %s)", nameOfNode);
		return NULL; // ERRORRR
	}

	IXML_Node *node_text = ixmlNode_getFirstChild(node);
	tmp=(char *)ixmlCloneDOMString(ixmlNode_getNodeValue(node_text));
	if(tmp == NULL) return strdup("");
	return tmp;
}
